/*
 * Point.java  0.4.0 / Oct 24, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
package com.cute4j.swing.graphics;

/**
 * Point Class.
 *
 * @author Slobodan Vrkacevic
 * @version 0.4.0
 */
public class Point {

// Public Static Fields. -------------------------------------------------------

  /**
   * Point(0, 0) object.
   */
  public static final Point ZERO_POINT = new Point();

// Private Fields. -------------------------------------------------------------

  private final int x;
  private final int y;
  private int hashCode; // NOPMD

// Public Constructors. --------------------------------------------------------

  /**
   * Constructs new Point object.
   */
  public Point() {
    x = 0;
    y = 0;
  }

  /**
   * Constructs new Point object.
   *
   * @param x the x coordinate of the point
   * @param y the y coordinate of the point
   */
  public Point(int x, int y) {
    this.x = x;
    this.y = y;
  }

// Public Methods. -------------------------------------------------------------

  /**
   * Returns the x coordinate of the point.
   *
   * @return the x coordinate of the point
   */
  public int getX() {
    return x;
  }

  /**
   * Returns <i>y</i>-coordinate of the point.
   *
   * @return <i>y</i>-coordinate of the point
   */
  public int getY() {
    return y;
  }

  /**
   * Returns the distance from this point to a specified point.
   *
   * @param px the x coordinate of the specified point
   * @param py the y coordinate of the specified point
   *
   * @return the distance from this point to  a specified point
   */
  public double distance(int px, int py) { // NOPMD
    px -= getX();
    py -= getY();
    return Math.sqrt((px * px) + (py * py));
  }

  /**
   * Returns the distance from this point to a specified point.
   *
   * @param p the specified point
   *
   * @return the distance from this point to  a specified point
   */
  public double distance(Point p) {
    int px = p.getX() - getX();
    int py = p.getY() - getY();
    return Math.sqrt((px * px) + (py * py));
  }

  /**
   * Returns the square distance from this point to a specified point.
   *
   * @param px the x coordinate of the specified point
   * @param py the y coordinate of the specified point
   *
   * @return the square distance from this point to  a specified point
   */
  public double distanceSq(int px, int py) { // NOPMD
    px -= getX();
    py -= getY();
    return (px * px) + (py * py);
  }

  /**
   * Returns the square distance from this point to a specified point.
   *
   * @param p the specified point
   *
   * @return the square distance from this point to  a specified point
   */
  public double distanceSq(Point p) {
    int px = p.getX() - getX();
    int py = p.getY() - getY();
    return (px * px) + (py * py);
  }

  /**
   * Returns translated point at location
   * (<tt>x</tt>&nbsp;<tt>+</tt>&nbsp;<tt>dx</tt>,
   * <tt>y</tt>&nbsp;<tt>+</tt>&nbsp;<tt>dy</tt>).
   *
   * @param dx the distance to move the point along the <i>x</i> axis
   * @param dy the distance to move the point along the <i>y</i> axis
   *
   * @return translated point
   */
  public Point translate(int dx, int dy) {
    return new Point(getX() + dx, getY() + dy);
  }

// Overridden Methods. ---------------------------------------------------------

  /**
   * {@inheritDoc}
   */
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if ((obj != null) && (obj.getClass() == getClass())) {
      Point point = (Point)obj;
      return ((point.getX() == getX()) && (point.getY() == getY()));
    }
    return false;
  }

  /**
   * {@inheritDoc}
   */
  public int hashCode() {
    if (hashCode == 0) {
      int hashCode = 127;
      hashCode = 167 * hashCode + getX();
      hashCode = 167 * hashCode + getY();
      this.hashCode = hashCode;
    }
    return hashCode;
  }

  /**
   * {@inheritDoc}
   */
  public String toString() {
    return getClass().getName() + "[x=" + getX() + ",y=" + getY() + "]";
  }

}
